#coding=utf-8

#创建一个自动化浏览器操作的类，这个类里面会写上不同关键字对应的操作函数
class autoTest():
    #导入所有会用到的模块
    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support.ui import Select,WebDriverWait
    import time,SendKeys
    
    #创建构造函数，在这个函数中需要创建所以的函数都会用到的浏览器
    def __init__(self):
        self.driver = self.webdriver.Chrome()
     
    #创建打开浏览器的方法，这个方法需要接收打开的url地址，并且定义一个等待时间
    def open_(self,data,time=10):
        '''
        data: 这个是浏览器的url地址
        time: 这个是用户定义的全局等待时间，默认值是10秒
        '''
        driver = self.driver
        driver.get(data)
        driver.maximize_window()
        driver.implicitly_wait(time)
        
    #创建一个单独来未元素查找位置的函数，因为这个函数只是类里面的函数需要调用，而不希望给外面的人看见，所以定义成私有的,
    #接收的是元素的定位方法和具体的位置
    def __getElement(self,method,pos):    
        #为了防止一旦元素没有找到，会报错中断程序，所以将定位写在try语句中
        driver = self.driver
        try:
            if method == "id":
                ele = self.WebDriverWait(driver,20,1).until(lambda driver:driver.find_element_by_id(pos))     
            elif method == "name":
                ele = self.WebDriverWait(driver,20,1).until(lambda driver:driver.find_element_by_name(pos))
            elif method == "link":
                ele = self.WebDriverWait(driver,20,1).until(lambda driver:driver.find_element_by_link_text(pos))
            elif method == "class":
                ele = self.WebDriverWait(driver,20,1).until(lambda driver:driver.find_element_by_class_name(pos))
            elif method == "xpath":
                ele = self.WebDriverWait(driver,20,1).until(lambda driver:driver.find_element_by_xpath(pos))
            else:
                print "请联系管理员添加你要的定位方法"
        #如果没有定位到元素的位置
        except Exception:
            #有任何的报错和异常，都用截图保存下来当时的页面内容
            import datetime
            t = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
            driver.get_screenshot_as_file("F:/shot/%s.png"%(t))
            #返回空值给调用的地方
            return None
        #如果找到了这个元素的位置
        else:
            return ele
    
    
    #创建输入的操作方法，需要接收输入值，定位方法，和具体的位置
    def input_(self,data,method,pos):
        #因为在很多的操作中，都需要用到元素的定位
        #所以我们把定位单独拿出来，变成一个函数
        ele = self.__getElement(method,pos)
        #判断一下，定位函数返回的值是什么，如果返回none表示元素不存在
        if ele == None:
            print "输入框的元素没有找到"
        else:
            ele.clear()
            ele.send_keys(data)
    
    #创建点击的操作方法，需要接收定位方法，和具体的位置
    def click_(self,method,pos):
        #因为在很多的操作中，都需要用到元素的定位
        #所以我们把定位单独拿出来，变成一个函数
        ele = self.__getElement(method,pos)
        #判断一下，定位函数返回的值是什么，如果返回none表示元素不存在
        if ele == None:
            print "输入框的元素没有找到"
        else:
            ele.click()
    
    #创建对子页面的操作，分别有进入子页面，返回父级页面，跳转到最外层页面
    def frame_(self,data,method,pos):
        '''
        0：表示进入子页面
        1：表示返回父页面
        2：表示跳转到最外层页面
        '''
        if data == "0":
            ele = self.__getElement(method, pos)
            if ele == None:
                print "切换的子页面标签没有找到"
            else:
                self.driver.switch_to.frame(ele)
        elif data == "1":
            self.driver.switch_to.parent_frame()
        elif data == "2":
            self.driver.switch_to.default_content()
        else:
            print "请填写状态码：0：表示进入子页面；1：表示返回父页面；2：表示跳转到最外层页面"
    
    #创建在浏览器中输入js来修改元素属性的操作
    def js_(self,data):
        self.driver.execute_script(data)
        
    #创建键盘按键发送的操作方法
    def keys_(self,data):
        #按键发送的内容只能是utf8的字符格式，不能是unicode，所以需要对内容进行转码
        data = data.encode('utf8')
        self.time.sleep(2)
        self.SendKeys.SendKeys(data)
    
    #创建针对select标准下拉框的操作方法
    def select_(self,data,method,pos):
        ele = self.__getElement(method, pos)
        if ele == None:
            print "select下拉框没有找到"
        else:
            s = self.Select(ele)
            #因为value是select中比较稳定的值，所以固定用value值来选择下拉框
            s.select_by_value(data)
    
    #创建聚焦到新窗口元素的方法,data接收的是要切换的页面的序号
    def window_(self,data):
        '''
        -1：表示最新的窗口
        0：表示第一个窗口
        1：表示第二个窗口
                    依次类推
        '''
        #因为文档中所有的data都统一保存成了unicode字符串的格式，所以序号需要将字符串转换成整型
        data = int(data)
        h = self.driver.window_handles
        self.driver.switch_to.window(h[data])
        
    #创建鼠标的操作方法
    def mouse_(self,data,method,pos,status):
        action = self.ActionChains(self.driver)
        
        #判断鼠标需要用哪种操作方法
        #先判断点击的操作
        if status == "click":
            ele = self.__getElement(method, pos)
            if ele == None:
                print "要用鼠标点击的元素没有找到"
            else:
                action.click(ele).perform()
        #判断需要使用鼠标来输入内容
        elif status == "input":
            action.clear()
            action.send_keys(data).perform()
        #判断需要移动鼠标到某个元素上面
        elif status == "move":
            ele = self.__getElement(method, pos)
            if ele == None:
                print "没有找到需要移动到的元素"
            else:
                action.move_to_element(ele).perform()
        #判断需要使用鼠标将一个元素拖到另一个元素的位置上去
        elif status == "drag":
            #先获取鼠标要拖动的元素原位置
            source = self.__getElement(method, pos)
            #获取鼠标要拖动到的目标位置
            '''
            xpath=//a[text()='中文']
            id=id值
            name=name值
            '''
            #先使用=号来切割这个字符串，方法就是切割后得到的列表的第一个元素
            #位置就是切割后列表剩下的所有位置拼接起来的总和
            data = data.split("=")
            #保存第一个位置给method
            method = data[0]
            #因为方法已经取出来了，所以将它从列表中删除掉
            data.pop(0)
            #再使用=号拼接剩下的列表位置
            pos = "=".join(data)
            target = self.__getElement(method, pos)
            if source == None or target == None:
                print "拖动的原位置或者目标位置没有找到"
            else:
                action.drag_and_drop(source,target).perform()
        #剩下的方法还没有定义
        else:
            print "功能还没有开发"
    
    #创建一个检查预期结果的函数
    def check_(self,method,pos):
        ele = self.__getElement(method, pos)
        #有可能会返回结果，也有可能会返回空值
        return ele
        
        
    
    
    
    
    
    
    
    
    
    
    
        
        
        
        
        